package com.xinshujia.config.authentication.provider;

import com.xinshujia.config.authentication.service.MyUserDetailsService;
import com.xinshujia.dto.UserDTO;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

/**
 * @author: 野狼上校
 * @since: 2024-08-03 15:12
 * @version: 1.0
 * @descript:
 */
@Component
public class MyLoginProvider implements AuthenticationProvider {
 private final MyUserDetailsService myUserDetailsService;

 public MyLoginProvider(MyUserDetailsService myUserDetailsService) {
  this.myUserDetailsService = myUserDetailsService;
 }

 @Override
 public Authentication authenticate(Authentication authentication) throws AuthenticationException {
  // 1. 获取用户输入的信息
  UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = (UsernamePasswordAuthenticationToken) authentication;
  String username = (String) usernamePasswordAuthenticationToken.getPrincipal();
  String password = (String) usernamePasswordAuthenticationToken.getCredentials();

  // 2. 根据手机号码从数据库中查询用户信息
  UserDTO userDTO = (UserDTO) myUserDetailsService.loadUserByUsername(username);
  if (ObjectUtils.isEmpty(userDTO)) {
   throw new BadCredentialsException("账号不存在");
  }
  // 3. 验证密码是否正确(使用DelegatingPasswordEncode加密方案)
  PasswordEncoder delegatingPasswordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
  boolean matches = delegatingPasswordEncoder.matches(authentication.getCredentials().toString(), userDTO.getPassword());
  if (!matches) {
   throw new BadCredentialsException("密码不正确");
  }
  // 4. 把用户信息封装到PhoneAuthenticationToken中
  UsernamePasswordAuthenticationToken usernameAuthenticationTokenFull = new UsernamePasswordAuthenticationToken(userDTO, password, userDTO.getAuthorities());
  usernameAuthenticationTokenFull.setDetails(usernamePasswordAuthenticationToken.getDetails());
  return usernameAuthenticationTokenFull;
 }

 @Override
 public boolean supports(Class<?> authentication) {
  return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
 }
}